{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1e2bb476",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.layers import Dropout, Dense, SimpleRNN\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "import pandas as pd\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "from sklearn.metrics import mean_squared_error, mean_absolute_error\n",
    "import math"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c8957e76",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "numpy 1.21.4\n",
      "pandas 1.3.4\n",
      "tensorflow 2.7.0\n"
     ]
    }
   ],
   "source": [
    "for module in np, pd, tf:\n",
    "     print (module.__name__, module.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "247a90dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 这两行代码解决 plt 中文显示的问题\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "plt.rcParams['axes.unicode_minus'] = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f298f448",
   "metadata": {},
   "outputs": [],
   "source": [
    "stock = pd.read_csv('../dataset/600031.csv')  # 读取股票文件\n",
    "# stock = stock.drop(['成交额'],axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "33c8d18c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>日期</th>\n",
       "      <th>开盘</th>\n",
       "      <th>收盘</th>\n",
       "      <th>最高</th>\n",
       "      <th>最低</th>\n",
       "      <th>成交量</th>\n",
       "      <th>成交额</th>\n",
       "      <th>振幅</th>\n",
       "      <th>涨跌幅</th>\n",
       "      <th>涨跌额</th>\n",
       "      <th>换手率</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2020-11-09</td>\n",
       "      <td>27.80</td>\n",
       "      <td>27.54</td>\n",
       "      <td>28.14</td>\n",
       "      <td>26.89</td>\n",
       "      <td>856249</td>\n",
       "      <td>2348800992</td>\n",
       "      <td>4.55</td>\n",
       "      <td>0.18</td>\n",
       "      <td>0.05</td>\n",
       "      <td>1.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2020-11-10</td>\n",
       "      <td>27.98</td>\n",
       "      <td>27.32</td>\n",
       "      <td>27.98</td>\n",
       "      <td>26.91</td>\n",
       "      <td>558824</td>\n",
       "      <td>1523209504</td>\n",
       "      <td>3.89</td>\n",
       "      <td>-0.80</td>\n",
       "      <td>-0.22</td>\n",
       "      <td>0.66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2020-11-11</td>\n",
       "      <td>27.33</td>\n",
       "      <td>28.31</td>\n",
       "      <td>28.86</td>\n",
       "      <td>27.21</td>\n",
       "      <td>1015374</td>\n",
       "      <td>2873205488</td>\n",
       "      <td>6.04</td>\n",
       "      <td>3.62</td>\n",
       "      <td>0.99</td>\n",
       "      <td>1.20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2020-11-12</td>\n",
       "      <td>28.31</td>\n",
       "      <td>28.70</td>\n",
       "      <td>28.88</td>\n",
       "      <td>27.91</td>\n",
       "      <td>718595</td>\n",
       "      <td>2041558432</td>\n",
       "      <td>3.43</td>\n",
       "      <td>1.38</td>\n",
       "      <td>0.39</td>\n",
       "      <td>0.85</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2020-11-13</td>\n",
       "      <td>28.28</td>\n",
       "      <td>28.16</td>\n",
       "      <td>28.50</td>\n",
       "      <td>27.60</td>\n",
       "      <td>674807</td>\n",
       "      <td>1888773520</td>\n",
       "      <td>3.14</td>\n",
       "      <td>-1.88</td>\n",
       "      <td>-0.54</td>\n",
       "      <td>0.80</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           日期     开盘     收盘     最高     最低      成交量         成交额    振幅   涨跌幅  \\\n",
       "0  2020-11-09  27.80  27.54  28.14  26.89   856249  2348800992  4.55  0.18   \n",
       "1  2020-11-10  27.98  27.32  27.98  26.91   558824  1523209504  3.89 -0.80   \n",
       "2  2020-11-11  27.33  28.31  28.86  27.21  1015374  2873205488  6.04  3.62   \n",
       "3  2020-11-12  28.31  28.70  28.88  27.91   718595  2041558432  3.43  1.38   \n",
       "4  2020-11-13  28.28  28.16  28.50  27.60   674807  1888773520  3.14 -1.88   \n",
       "\n",
       "    涨跌额   换手率  \n",
       "0  0.05  1.01  \n",
       "1 -0.22  0.66  \n",
       "2  0.99  1.20  \n",
       "3  0.39  0.85  \n",
       "4 -0.54  0.80  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stock.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15bdcbdf",
   "metadata": {},
   "source": [
    "### 用多特征预测股价\n",
    "### 将数据集分成训练集：测试集 == 4:1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c46c880d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 取除日期外全部特征\n",
    "training_set = stock.iloc[0:int(len(stock) / 5 * 4), 1:].values\n",
    "test_set = stock.iloc[int(len(stock) / 5 * 4):, 1:].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "fcbfd899",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((201, 10), (51, 10))"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "training_set.shape , test_set.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3c6b862",
   "metadata": {},
   "source": [
    "# 归一化处理（进行缩放）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "d2ee46e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 归一化\n",
    "sc = MinMaxScaler(feature_range=(0, 1))  # 定义归一化：归一化到(0，1)之间\n",
    "# 缩放\n",
    "training_set_scaled = sc.fit_transform(training_set)  # 求得训练集的最大值，最小值这些训练集固有的属性，并在训练集上进行归一化\n",
    "test_set = sc.transform(test_set)  # 利用训练集的属性对测试集进行归一化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "9310a93f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 参数设置\n",
    "# 步进值\n",
    "seq_len = 5"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6b53e2d",
   "metadata": {},
   "source": [
    "# 训练集处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "c4720fa9",
   "metadata": {},
   "outputs": [],
   "source": [
    "x_train = []\n",
    "y_train = []\n",
    "\n",
    "# 数据进行分组\n",
    "for i in range(seq_len, len(training_set_scaled)):\n",
    "    # 全部特征\n",
    "    x_train.append(training_set_scaled[i - seq_len:i, 0:])\n",
    "    # 收盘价\n",
    "    y_train.append(training_set_scaled[i, list(stock.iloc[0:int(len(stock) / 5 * 4), 1:].columns).index('收盘')])\n",
    "\n",
    "# 对训练集进行打乱\n",
    "np.random.seed(7)\n",
    "np.random.shuffle(x_train)\n",
    "np.random.seed(7)\n",
    "np.random.shuffle(y_train)\n",
    "tf.random.set_seed(7)\n",
    "\n",
    "# 将训练集由list格式变为array格式\n",
    "x_train, y_train = np.array(x_train), np.array(y_train)\n",
    "x_train = np.reshape(x_train, (x_train.shape[0], seq_len, training_set.shape[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f4d9e55",
   "metadata": {},
   "source": [
    "# 测试集处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "807b27a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "x_test = []\n",
    "y_test = []\n",
    "\n",
    "# 利用for循环，遍历整个测试集，提取测试集中连续5天的开盘价作为输入特征x_train，第6天的数据作为标签\n",
    "for i in range(seq_len, len(test_set)):\n",
    "    # 全部特征\n",
    "    x_test.append(test_set[i - seq_len:i, 0:])\n",
    "    # 收盘价\n",
    "    y_test.append(test_set[i, list(stock.iloc[0:int(len(stock) / 5 * 4), 1:].columns).index('收盘')])\n",
    "\n",
    "    # 测试集变array并reshape为符合RNN输入要求：[送入样本数， 循环核时间展开步数， 每个时间步输入特征个数]\n",
    "x_test, y_test = np.array(x_test), np.array(y_test)\n",
    "x_test = np.reshape(x_test, (x_test.shape[0], seq_len, test_set.shape[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e45bc36",
   "metadata": {},
   "source": [
    "# 构建模型\n",
    "\n",
    "### 序列化建模，一般步骤为：\n",
    "\n",
    "　　* 1、实例化一个Sequential类，该类是继承于Model类；\n",
    "\n",
    "　　* 2、添加所需要的神经网络层；\n",
    "\n",
    "　　* 3、用compile进行编译模型；\n",
    "\n",
    "　　* 4、用fit训练模型；\n",
    "\n",
    "　　* 5、用predict预测。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "6f2d3b77",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = tf.keras.Sequential([\n",
    "    SimpleRNN(80, return_sequences=True),\n",
    "    Dropout(0.2),\n",
    "    SimpleRNN(100),\n",
    "    Dropout(0.2),\n",
    "    Dense(1)\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "d6fb9d91",
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(optimizer=tf.keras.optimizers.Adam(0.001),loss='mean_squared_error')  \n",
    "# 损失函数用均方误差\n",
    "# 该应用只观测loss数值，不观测准确率，所以删去metrics选项，一会在每个epoch迭代显示时只显示loss值"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c4c9c0db",
   "metadata": {},
   "source": [
    "# 预测一次，并保存预测结构，用于之后的验证"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "1f8a0afa",
   "metadata": {},
   "outputs": [],
   "source": [
    "checkpoint_save_path = \"./checkpoint/rnn_stock.ckpt\"\n",
    "if os.path.exists(checkpoint_save_path + '.index'):\n",
    "    print('-------------load the model-----------------')\n",
    "    model.load_weights(checkpoint_save_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e071782a",
   "metadata": {},
   "source": [
    "# 参数详解：\n",
    "* x=None, #输入的x值\n",
    "* y=None, #输入的y标签值\n",
    "* batch_size=None, #整数 ，每次梯度更新的样本数即批量大小。未指定，默认为32。\n",
    "* epochs=1, #迭代次数\n",
    "* verbose=1, #整数，代表以什么形式来展示日志状态，\n",
    "* verbose = 0 为不在标准输出流输出日志信息，verbose = 1 为输出进度条记录，verbose = 2 为每个epoch输出一行记录\n",
    "* callbacks=None, #回调函数，这个list中的回调函数将会在训练过程中的适当时机被调用，参考回调函数\n",
    "* validation_split=0.0, #浮点数0-1之间，用作验证集的训练数据的比例。模型将分出一部分不会被训练的验证数据，并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。\n",
    "* validation_data=None, #这个参数会覆盖 validation_split\n",
    "   即两个函数只能存在一个，它的输入为元组 (x_val，y_val)，这作为验证数据。\n",
    "* shuffle=True, #布尔值。是否在每轮迭代之前混洗数据\n",
    "* class_weight=None,\n",
    "* sample_weight=None, \n",
    "* initial_epoch=0, \n",
    "* steps_per_epoch=None, #一个epoch包含的步数（每一步是一个batch的数据送入）\n",
    "   当使用如TensorFlow数据Tensor之类的输入张量进行训练时，默认的None代表自动分割，即数据集样本数/batch样本数。\n",
    "* validation_steps=None, #在验证集上的step总数，仅当steps_per_epoch被指定时有用。\n",
    "* validation_freq=1, #指使用验证集实施验证的频率。当等于1时代表每个epoch结束都验证一次\n",
    "* max_queue_size=10,\n",
    "* workers=1,\n",
    "* use_multiprocessing=False   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "9cc9532d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 训练参数\n",
    "batch_size = 64\n",
    "epochs = 100\n",
    "validation_freq=1\n",
    "# 等等"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "5da0f3b6",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "4/4 [==============================] - 4s 199ms/step - loss: 0.8071 - val_loss: 0.2196\n",
      "Epoch 2/100\n",
      "4/4 [==============================] - 0s 30ms/step - loss: 0.3128 - val_loss: 0.1744\n",
      "Epoch 3/100\n",
      "4/4 [==============================] - 0s 31ms/step - loss: 0.5727 - val_loss: 0.0119\n",
      "Epoch 4/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.1699 - val_loss: 0.1061\n",
      "Epoch 5/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.3272 - val_loss: 0.0133\n",
      "Epoch 6/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.1565 - val_loss: 0.0739\n",
      "Epoch 7/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.2358 - val_loss: 0.0192\n",
      "Epoch 8/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.1259 - val_loss: 0.0264\n",
      "Epoch 9/100\n",
      "4/4 [==============================] - 0s 34ms/step - loss: 0.1868 - val_loss: 0.0106\n",
      "Epoch 10/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0981 - val_loss: 0.0113\n",
      "Epoch 11/100\n",
      "4/4 [==============================] - 0s 35ms/step - loss: 0.1261 - val_loss: 0.0095\n",
      "Epoch 12/100\n",
      "4/4 [==============================] - 0s 29ms/step - loss: 0.0849 - val_loss: 0.0035\n",
      "Epoch 13/100\n",
      "4/4 [==============================] - 0s 17ms/step - loss: 0.0747 - val_loss: 0.0085\n",
      "Epoch 14/100\n",
      "4/4 [==============================] - 0s 29ms/step - loss: 0.0955 - val_loss: 0.0034\n",
      "Epoch 15/100\n",
      "4/4 [==============================] - 0s 33ms/step - loss: 0.0956 - val_loss: 0.0020\n",
      "Epoch 16/100\n",
      "4/4 [==============================] - 0s 32ms/step - loss: 0.0678 - val_loss: 0.0015\n",
      "Epoch 17/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0832 - val_loss: 0.0033\n",
      "Epoch 18/100\n",
      "4/4 [==============================] - 0s 30ms/step - loss: 0.0890 - val_loss: 0.0011\n",
      "Epoch 19/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0549 - val_loss: 0.0065\n",
      "Epoch 20/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0573 - val_loss: 0.0098\n",
      "Epoch 21/100\n",
      "4/4 [==============================] - 0s 29ms/step - loss: 0.0727 - val_loss: 0.0028\n",
      "Epoch 22/100\n",
      "4/4 [==============================] - 0s 28ms/step - loss: 0.0645 - val_loss: 0.0088\n",
      "Epoch 23/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0596 - val_loss: 0.0120\n",
      "Epoch 24/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0556 - val_loss: 0.0038\n",
      "Epoch 25/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0475 - val_loss: 0.0019\n",
      "Epoch 26/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.0395 - val_loss: 0.0014\n",
      "Epoch 27/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0522 - val_loss: 0.0016\n",
      "Epoch 28/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0568 - val_loss: 0.0053\n",
      "Epoch 29/100\n",
      "4/4 [==============================] - 0s 17ms/step - loss: 0.0513 - val_loss: 0.0109\n",
      "Epoch 30/100\n",
      "4/4 [==============================] - 0s 17ms/step - loss: 0.0501 - val_loss: 0.0039\n",
      "Epoch 31/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0542 - val_loss: 0.0024\n",
      "Epoch 32/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0627 - val_loss: 0.0033\n",
      "Epoch 33/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0435 - val_loss: 0.0015\n",
      "Epoch 34/100\n",
      "4/4 [==============================] - ETA: 0s - loss: 0.050 - 0s 26ms/step - loss: 0.0574 - val_loss: 0.0012\n",
      "Epoch 35/100\n",
      "4/4 [==============================] - 0s 34ms/step - loss: 0.0348 - val_loss: 0.0010\n",
      "Epoch 36/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0444 - val_loss: 0.0018\n",
      "Epoch 37/100\n",
      "4/4 [==============================] - 0s 40ms/step - loss: 0.0403 - val_loss: 8.6326e-04\n",
      "Epoch 38/100\n",
      "4/4 [==============================] - 0s 48ms/step - loss: 0.0370 - val_loss: 7.9346e-04\n",
      "Epoch 39/100\n",
      "4/4 [==============================] - 0s 26ms/step - loss: 0.0398 - val_loss: 0.0014\n",
      "Epoch 40/100\n",
      "4/4 [==============================] - 0s 17ms/step - loss: 0.0386 - val_loss: 8.3221e-04\n",
      "Epoch 41/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0336 - val_loss: 0.0011\n",
      "Epoch 42/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.0444 - val_loss: 0.0020\n",
      "Epoch 43/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0309 - val_loss: 7.9513e-04\n",
      "Epoch 44/100\n",
      "4/4 [==============================] - 0s 27ms/step - loss: 0.0336 - val_loss: 0.0026\n",
      "Epoch 45/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0325 - val_loss: 0.0036\n",
      "Epoch 46/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0315 - val_loss: 0.0025\n",
      "Epoch 47/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0353 - val_loss: 9.7410e-04\n",
      "Epoch 48/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0289 - val_loss: 0.0039\n",
      "Epoch 49/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.0310 - val_loss: 0.0061\n",
      "Epoch 50/100\n",
      "4/4 [==============================] - 0s 26ms/step - loss: 0.0375 - val_loss: 0.0032\n",
      "Epoch 51/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0350 - val_loss: 0.0058\n",
      "Epoch 52/100\n",
      "4/4 [==============================] - 0s 17ms/step - loss: 0.0353 - val_loss: 0.0055\n",
      "Epoch 53/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0385 - val_loss: 0.0020\n",
      "Epoch 54/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.0346 - val_loss: 0.0016\n",
      "Epoch 55/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0340 - val_loss: 0.0019\n",
      "Epoch 56/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0407 - val_loss: 0.0043\n",
      "Epoch 57/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0296 - val_loss: 0.0068\n",
      "Epoch 58/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0326 - val_loss: 0.0011\n",
      "Epoch 59/100\n",
      "4/4 [==============================] - 0s 17ms/step - loss: 0.0257 - val_loss: 0.0010\n",
      "Epoch 60/100\n",
      "4/4 [==============================] - 0s 43ms/step - loss: 0.0348 - val_loss: 6.7305e-04\n",
      "Epoch 61/100\n",
      "4/4 [==============================] - 0s 28ms/step - loss: 0.0283 - val_loss: 9.1455e-04\n",
      "Epoch 62/100\n",
      "4/4 [==============================] - 0s 28ms/step - loss: 0.0280 - val_loss: 9.3059e-04\n",
      "Epoch 63/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0235 - val_loss: 0.0010\n",
      "Epoch 64/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0244 - val_loss: 0.0013\n",
      "Epoch 65/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.0279 - val_loss: 0.0013\n",
      "Epoch 66/100\n",
      "4/4 [==============================] - 0s 30ms/step - loss: 0.0243 - val_loss: 9.6233e-04\n",
      "Epoch 67/100\n",
      "4/4 [==============================] - 0s 26ms/step - loss: 0.0276 - val_loss: 7.8679e-04\n",
      "Epoch 68/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0256 - val_loss: 0.0015\n",
      "Epoch 69/100\n",
      "4/4 [==============================] - 0s 35ms/step - loss: 0.0255 - val_loss: 6.3718e-04\n",
      "Epoch 70/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0215 - val_loss: 0.0015\n",
      "Epoch 71/100\n",
      "4/4 [==============================] - 0s 17ms/step - loss: 0.0200 - val_loss: 0.0031\n",
      "Epoch 72/100\n",
      "4/4 [==============================] - 0s 17ms/step - loss: 0.0287 - val_loss: 0.0024\n",
      "Epoch 73/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0229 - val_loss: 6.9371e-04\n",
      "Epoch 74/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0204 - val_loss: 0.0011\n",
      "Epoch 75/100\n",
      "4/4 [==============================] - 0s 49ms/step - loss: 0.0252 - val_loss: 6.3406e-04\n",
      "Epoch 76/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0216 - val_loss: 6.8379e-04\n",
      "Epoch 77/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0221 - val_loss: 6.7491e-04\n",
      "Epoch 78/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0213 - val_loss: 0.0021\n",
      "Epoch 79/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0210 - val_loss: 0.0044\n",
      "Epoch 80/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0183 - val_loss: 0.0025\n",
      "Epoch 81/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0232 - val_loss: 7.7077e-04\n",
      "Epoch 82/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0187 - val_loss: 6.5168e-04\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 83/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0175 - val_loss: 6.4819e-04\n",
      "Epoch 84/100\n",
      "4/4 [==============================] - 0s 26ms/step - loss: 0.0178 - val_loss: 0.0013\n",
      "Epoch 85/100\n",
      "4/4 [==============================] - 0s 29ms/step - loss: 0.0191 - val_loss: 9.8184e-04\n",
      "Epoch 86/100\n",
      "4/4 [==============================] - 0s 28ms/step - loss: 0.0205 - val_loss: 6.6361e-04\n",
      "Epoch 87/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0194 - val_loss: 0.0010\n",
      "Epoch 88/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0213 - val_loss: 0.0017\n",
      "Epoch 89/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0207 - val_loss: 0.0026\n",
      "Epoch 90/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0255 - val_loss: 0.0029\n",
      "Epoch 91/100\n",
      "4/4 [==============================] - 0s 17ms/step - loss: 0.0230 - val_loss: 7.9745e-04\n",
      "Epoch 92/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0185 - val_loss: 9.5363e-04\n",
      "Epoch 93/100\n",
      "4/4 [==============================] - 0s 27ms/step - loss: 0.0213 - val_loss: 0.0022\n",
      "Epoch 94/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0209 - val_loss: 0.0018\n",
      "Epoch 95/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0193 - val_loss: 9.8484e-04\n",
      "Epoch 96/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0143 - val_loss: 0.0019\n",
      "Epoch 97/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0141 - val_loss: 0.0015\n",
      "Epoch 98/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0207 - val_loss: 7.4875e-04\n",
      "Epoch 99/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0153 - val_loss: 6.3859e-04\n",
      "Epoch 100/100\n",
      "4/4 [==============================] - 0s 34ms/step - loss: 0.0134 - val_loss: 6.0600e-04\n",
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      " Layer (type)                Output Shape              Param #   \n",
      "=================================================================\n",
      " simple_rnn (SimpleRNN)      (None, 5, 80)             7280      \n",
      "                                                                 \n",
      " dropout (Dropout)           (None, 5, 80)             0         \n",
      "                                                                 \n",
      " simple_rnn_1 (SimpleRNN)    (None, 100)               18100     \n",
      "                                                                 \n",
      " dropout_1 (Dropout)         (None, 100)               0         \n",
      "                                                                 \n",
      " dense (Dense)               (None, 1)                 101       \n",
      "                                                                 \n",
      "=================================================================\n",
      "Total params: 25,481\n",
      "Trainable params: 25,481\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,\n",
    "                                                 save_weights_only=True,\n",
    "                                                 save_best_only=True,\n",
    "                                                 monitor='val_loss')\n",
    "\n",
    "_model = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_test, y_test), validation_freq=validation_freq,\n",
    "                   callbacks=[cp_callback])\n",
    "\n",
    "model.summary()\n",
    "\n",
    "file = open('./weights.txt', 'w')  # 参数提取\n",
    "for v in model.trainable_variables:\n",
    "    file.write(str(v.name) + '\\n')\n",
    "    file.write(str(v.shape) + '\\n')\n",
    "    file.write(str(v.numpy()) + '\\n')\n",
    "file.close()\n",
    "\n",
    "loss = _model.history['loss']\n",
    "val_loss = _model.history['val_loss']\n",
    "\n",
    "plt.plot(loss, label='训练损失')\n",
    "plt.plot(val_loss, label='测试损失')\n",
    "plt.title('训练和测试损失')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "cf550192",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 预测\n",
    "# 测试集输入模型进行预测\n",
    "predicted_stock_price = model.predict(x_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "368f9504",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 归一时是对所有数据列进行的归一\n",
    "# 补充数据列之后才能进行反归一\n",
    "predicted_df = pd.DataFrame(test_set[seq_len:])\n",
    "predicted_df.iloc[:, list(stock.iloc[0:int(len(stock) / 5 * 4), 1:].columns).index('收盘')] = predicted_stock_price\n",
    "predicted_df.head()\n",
    "predicted_set = predicted_df.values\n",
    "# 对预测数据还原---从（0，1）反归一化到原始范围\n",
    "predicted_stock_price = sc.inverse_transform(predicted_set)\n",
    "# 对真实数据还原---从（0，1）反归一化到原始范围\n",
    "real_stock_price = sc.inverse_transform(test_set[seq_len:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "2dc1b548",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 只取收盘价\n",
    "real_stock_price = real_stock_price[:,list(stock.iloc[0:int(len(stock) / 5 * 4), 1:].columns).index('收盘')]\n",
    "predicted_stock_price = predicted_stock_price[:,list(stock.iloc[0:int(len(stock) / 5 * 4), 1:].columns).index('收盘')]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "b968b0a9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 画出真实数据和预测数据的对比曲线\n",
    "plt.plot(real_stock_price, color='red', label='股票价格')\n",
    "plt.plot(predicted_stock_price, color='blue', label='预测股票价格')\n",
    "plt.title('股票价格预测')\n",
    "plt.xlabel('时间')\n",
    "plt.ylabel('股票价格')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "3b2fbfd3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "均方误差: 0.323646\n",
      "均方根误差: 0.568899\n",
      "平均绝对误差: 0.439249\n"
     ]
    }
   ],
   "source": [
    "# 评估\n",
    "# calculate MSE 均方误差 ---> E[(预测值-真实值)^2] (预测值减真实值求平方后求均值)\n",
    "mse = mean_squared_error(predicted_stock_price, real_stock_price)\n",
    "# calculate RMSE 均方根误差--->sqrt[MSE]    (对均方误差开方)\n",
    "rmse = math.sqrt(mean_squared_error(predicted_stock_price, real_stock_price))\n",
    "# calculate MAE 平均绝对误差----->E[|预测值-真实值|](预测值减真实值求绝对值后求均值）\n",
    "mae = mean_absolute_error(predicted_stock_price, real_stock_price)\n",
    "print('均方误差: %.6f' % mse)\n",
    "print('均方根误差: %.6f' % rmse)\n",
    "print('平均绝对误差: %.6f' % mae)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "fb5827cd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "准确率：0.9841606630012542\n"
     ]
    }
   ],
   "source": [
    "#ACC\n",
    "error = 0\n",
    "summery = 0\n",
    "for i in range(24):\n",
    "    error += abs(predicted_stock_price[i] - real_stock_price[i])\n",
    "    summery += real_stock_price[i]\n",
    "acc = 1 - error/summery\n",
    "print(\"准确率：{}\".format(acc))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "deep",
   "language": "python",
   "name": "deep"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
